<!-- directive:title liuyp::$q服务详解-AngularJS中的Promise -->
<!-- directive:breadcrumb AngularJS中的Promise -->
<div class="panel-body">
    <article class="docs-content">
        <p>先说说什么是Promise，什么是$q吧。</p>
        <pre>Promise是一种异步处理模式，有很多的实现方式，用处比较多的就是这一套了，语义化定义执行过程和回调过程。</pre>
        <div class="row">
            <div class="col-sm-6">
                <p>以前异步回调的代码，会让开发者陷入泥潭，无法跟踪</p>
                <pre better-pre>
                    funA(arg1,arg2,function(){
                        funcB(arg1,arg2,function(){
                            funcC(arg1,arg2,function(){
                                 xxxx....
                            })
                        })
                    })
                </pre>
            </div>
            <div class="col-sm-6">
                <p>但是有了Promise这种规范，它能帮助开发者用同步的方式，编写异步的代码</p>
                <pre better-pre>
                    deferABC.resolve(xxx)
                    .then(funcSuccess(){},funcError(){},funcNotify(){});
                    //类似
                    deferABC.resolve(function(){
                        Sunccess:funcSuccess,
                        error:funcError,
                        notify:funcNotify
                    })
                </pre>
            </div>
        </div>
        <p>再说的直白点</p>
        <p>Promise就是一种对执行结果不确定的一种预先定义，如果成功，就...；如果失败，就...， 就像事先给出了一些承诺/保证。</p>
        <p>所以这种结构也可以叫做<code>数据保证</code></p>
        <blockquote class="m-t">
            <p>比如，小白在上学时很懒，平时总让舍友带饭，并且事先跟他说好了 ::::::::::::::::::::</p>
            <p class="info">小白跟舍友说 : 如果有韭菜鸡蛋就买这个菜，否则就买西红柿炒鸡蛋；无论如何都要回来玩游戏。</p>
            <pre better-pre>
                舍友出去到回来() .then(
                    function(){ if(买到了韭菜鸡蛋) { 高兴的吃 } },
                    function(){ if(买到了买西红柿炒鸡蛋) { 嫌弃的吃 } }
                )
                .finally(function(){ 和室友玩游戏 })
            </pre>
            <p class="info">舍友有自己的想法 : 看情况吧</p>
            <pre better-pre>
                function 舍友出去到回来(){
                    return new Promise(买韭菜鸡蛋, 买西红柿炒鸡蛋){
                        if ( 看到饭馆A ) { 买韭菜鸡蛋 }
                        else if ( 看到饭馆B ) { 买西红柿炒鸡蛋 }
                        else if ( 看到网吧 ) { 泡一会 }
                    }
                }
            </pre>
        </blockquote>
        <hr />
        <p>q服务是AngularJS中自己封装实现的一种Promise实现，相对与Kris Kwal's Q要轻量级的多。</p>
        <p>在$q中，可以使用resolve方法，变成完成状态；使用reject方法，变成拒绝状态。</p>
        <script type="text/xianjs" ui-bs>
            function asyncGreet(name) {
                var deferred = $q.defer();
                // 通过$q.defer()创建一个deferred延迟对象，在创建一个deferred实例时，
                // 也会创建出来一个派生的promise对象，使用deferred.promise就可以检索到派生的promise。
                deferred.notify('About to greet ' + name + '.'); //延迟对象的notify方法。
                if (okToGreet(name)) {
                    deferred.resolve('Hello, ' + name + '!'); //任务被成功执行
                } else {
                    deferred.reject('Greeting ' + name + ' is not allowed.'); //任务未被成功执行
                }
                return deferred.promise; //返回deferred实例的promise对象
            }
            function okToGreet(name) {
                //只是mock数据，实际情况将根据相关业务实现代码
                if(name == 'Superman') return true;
                else return false;
            }
            var promise = asyncGreet('Superman'); //获得promise对象
            // promise对象的then函数会获得当前任务也就是当前deferred延迟实例的执行状态。
            // 它的三个回调函数分别会在resolve(), reject() 和notify()时被执行
            promise.then(function(greeting) {
                alert('Success: ' + greeting);
            }, function(reason) {
                alert('Failed: ' + reason);
            }, function(update) {
                alert('Got notification: ' + update);
            });
        </script>
        <p>其中defer()用于创建一个deferred对象，defer.promise用于返回一个promise对象，来定义then方法。</p>
        <p>其中resolve中传入的变量或者函数返回结果，会当作第一个then方法的参数。then方法会返回一个promise对象</p>
        <pre> xxxx .then(a,b,c) .then(a,b,c) .then(a,b,c) .catch() .finally()</pre>
        <p>它的用法与上面的有微妙的不同</p>
        <blockquote class="m-t">
            <p>比如，小白在上学时很懒，平时总让舍友带饭 ::::::::::::::::::::</p>
            <p>小白内心纠结了半天，想如果舍友A起来就买鸡蛋系列炒饭，别人的话就买肉系列炒饭。</p>
            <p>结果舍友A起来了，小白跟舍友说 : 如果有韭菜鸡蛋就买这个菜，否则就买西红柿炒鸡蛋；无论如何都要回来玩游戏。</p>
            <p>舍友有自己的想法 : 看情况吧</p>
            <pre better-pre>
                 app.controller("myctrl", ["$scope", "$q", function($scope, $q ){
                    事情1 = $q.defer().promise;
                    事情1
                    .then( //小白的内心纠结
                        舍友A起来就买鸡蛋系列炒饭 或者 别人的话就买肉系列炒饭,
                        都没起
                        function(value){ }
                    )
                    .then( //舍友出去到回来
                        买韭菜鸡蛋 或者 买西红柿炒鸡蛋,
                        没回来,
                        function(value){ }
                    )
                    .catch(function(e){ 没饭吃 })
                    .finally(function(value){ 和室友玩游戏 });
                    .resolve(有舍友A起来了);
                 }]);
            </pre>
        </blockquote>
    </article>
</div>
